import { segment } from 'icqq'
import fetch from 'node-fetch'
import fs from 'fs'
import { createRequire } from 'module'

const require = createRequire(import.meta.url)
const { exec } = require('child_process')
let cookie = ""
export class bv extends plugin {
    constructor() {
        super({
            name: '视频解析',
            dsc: '视频解析',
            event: 'message',
            priority: 100,
            rule: [
                {
                    reg: '',
                    fnc: 'bili'
                },
            ]
        })
    }

    async bili(e) {
        let msg = this.e.msg
        let ck = cookie
        let urllist = ['b23.tv', 'm.bilibili.com', 'www.bilibili.com']
        let reg2 = new RegExp(`${urllist[0]}|${urllist[1]}|${urllist[2]}`)
        if (!msg && this.e.raw_message != '[json消息]') return false
        if (this.e.raw_message == '[json消息]') {
            let json = JSON.parse(this.e.message[0].data)
            msg = msg || json.meta.detail_1?.qqdocurl || json.meta.news.jumpUrl
        }
        if (!msg.match(reg2)) return false

        const regurl = /(https?|http|ftp|file):\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]/g;

        let url = msg.match(regurl)[0]//'https://www.bilibili.com/video/BV19y4y1f7Rf/?spm_id_from=autoNext&vd_source=478dcc286bfddccd0df1500770bef5fc' //this.e.msg
        let bilireg = /(BV.*?).{10}/
        let bv = url.match(bilireg)
        let videoInfo = {};
        if (bv) {
            //存在bv长链接
            bv = bv[0]
        } else {
            //不存在短链接
            await fetch(url).then(res => {
                bv = res.url.match(bilireg)[0]
            })
        }

        await fetch(`http://api.bilibili.com/x/web-interface/view?bvid=${bv}`).then(async res => {
            let json = await res.json()
            let data = json.data
            videoInfo.bvid = data.bvid
            videoInfo.cid = data.cid
            videoInfo.owner = data.owner.name
            videoInfo.pic = data.pic //封面
            videoInfo.title = data.title //标题
            videoInfo.desc = data.desc //描述
            videoInfo.ctime = data.ctime //创建时间
            videoInfo.view = data.stat.view//播放量
            videoInfo.danmaku = data.stat.danmaku //弹幕数
            videoInfo.like = data.stat.like//点赞
            videoInfo.coin = data.stat.coin//投币
            videoInfo.favorite = data.stat.favorite//收藏
            videoInfo.share = data.stat.share//分享
            videoInfo.duration = data.duration//时长s
        })
        if (videoInfo.duration >= 480 && videoInfo.duration < 900) {
            ck = ''
            this.e.reply("检测到长视频，已降低视频质量以提高反应速度")
        }
        const downBiliFile = async (url, path, suc = () => { }) => {
            await fetch(url, {
                headers: {
                    'referer': `https://www.bilibili.com/`
                },

            }).then(async res => {
                let rep = await res.arrayBuffer()
                fs.writeFile(path, Buffer.from(rep), "binary", function (err) {
                    if (!err) {
                        suc()
                    }
                });
            })
        }
        let that = this
        let videourl, audioUrl;
        if (videoInfo.duration >= 900) {
            this.e.reply("检测到超长视频，已将视频质量调整到最低以提高反应速度")
            this.reply([segment.image(videoInfo.pic), `标题: ${videoInfo.title}\n`, `作者: ${videoInfo.owner}\n`, `${this.addnull(`播放量: ${this.computew(videoInfo.view)} 弹幕: ${this.computew(videoInfo.danmaku)}`, '弹')}\n`, `${this.addnull(`点赞: ${this.computew(videoInfo.like)}投币: ${this.computew(videoInfo.coin)}`, '投')}`, `\n${this.addnull(`收藏: ${this.computew(videoInfo.favorite)}转发: ${this.computew(videoInfo.share)}`, '转')}`])
            let videoPath = process.cwd() + '/bibilli.mp4'
            await fetch(`https://api.bilibili.com/x/player/playurl?bvid=${videoInfo.bvid}&cid=${videoInfo.cid}&qn=120`).then(async res => {
                let json = await res.json()
                let data = json.data
                videourl = data.durl[0].backup_url[0] || data.durl[0].backup_url[1] || data.durl[0].url
            })
            await downBiliFile(videourl, videoPath, () => {
                e.reply(segment.video(videoPath))
            })


        } else {
            this.reply([segment.image(videoInfo.pic), `标题: ${videoInfo.title}\n`, `作者: ${videoInfo.owner}\n`, `${this.addnull(`播放量: ${this.computew(videoInfo.view)} 弹幕: ${this.computew(videoInfo.danmaku)}`, '弹')}\n`, `${this.addnull(`点赞: ${this.computew(videoInfo.like)}投币: ${this.computew(videoInfo.coin)}`, '投')}`, `\n${this.addnull(`收藏: ${this.computew(videoInfo.favorite)}转发: ${this.computew(videoInfo.share)}`, '转')}`])
            await fetch(`https://www.bilibili.com/video/${bv}`, {
                headers: {
                    'User-Agent':
                        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.69',
                    referer: 'https://www.bilibili.com',
                    cookie: ck
                },
            }).then(async res => {
                let html = await res.text()
                let data = html.match(/<script>window\.__playinfo__=({.*})<\/script><script>/)?.[1]
                data = JSON.parse(data)
                videourl = data.data.dash.video[0]?.baseUrl ?? data.data.dash.video[0]?.backupUrl[0]
                audioUrl = data.data.dash.audio[0]?.baseUrl ?? data.data.dash.audio[0]?.backupUrl[0]
            })
            let videoPath = process.cwd() + '/bibilli.mp4'
            let audioPath = process.cwd() + '/bibilli.mp3'
            await downBiliFile(videourl, videoPath)
            await downBiliFile(audioUrl, audioPath)
            let resultPath = process.cwd() + '/result.mp4'
            exec(`ffmpeg -y -i ${videoPath} -i ${audioPath} -c copy ${resultPath}`, async function (err) {
                if (err) {
                    console.log(err);
                    fs.unlink(videoPath, f => f)
                    fs.unlink(audioPath, f => f)
                } else {
                    e.reply(segment.video(resultPath))
                }
            })
        }
    }


    computew(num) {
        return num >= 10000 ? (num / 10000).toFixed(1) + 'w' : num
    }

    addnull(str, target) {
        let idx = str.indexOf(target)
        console.log(idx);
        if (idx == 14) {
            return str
        } else if (idx < 14) {
            let arr = Array.from(str)
            let index = 14 - idx
            for (let i = 0; i < index; i++) {
                arr.splice(idx, 0, '  ')
            }
            return arr.join('')
        }
    }

}
